<?php
declare (strict_types = 1);
namespace app\admin\controller;

use think\Request;
use think\Exception;
use think\exception\ValidateException;

use think\facade\Db;
use service\JsonService as Json;
use app\admin\controller\BaseController;

use app\common\model\User;
use app\common\model\CheckRule;
use app\common\model\UserSection;
use app\common\model\UserSectionLevel;
use app\common\model\ApplyInduction;
use app\common\model\RuleSalary;
use app\common\model\UserWages;
use app\common\model\UserResume;
use app\common\model\SystemMenu;
use app\common\model\SystemRole;
use app\common\model\ResumeEducation;
use app\common\model\ResumeWork;
use app\common\model\UserCompany;
use app\common\model\ResumeJob;

use app\common\validate\UserValidate;
use LDAP\Result;

class UserController extends BaseController
{
    /** 个人信息 */
    public function getUserInfo()
    {   
        $field = 'id, name, staff_no, role_id, avatars, section_id, check_clock_id, card_num, is_trial, is_trial_salary, probation, job_time';
        $userInfo = User::getFind(['id' => $this->user_id], $field);
        
        if($userInfo === false) return Json::fail('账号不存在');

        $sectionInfo = UserSection::getFind(['id' => $userInfo['section_id']], 'name, expire_time');

        $userInfo['section'] = $sectionInfo['name'];
        $userInfo['expire_time'] = $sectionInfo['expire_time'] ? date('Y-m-d', $sectionInfo['expire_time']) : 0;

        if($userInfo['check_clock_id'] != 0){
            $checkRuleInfo = CheckRule::getFind(['id' => $userInfo['check_clock_id']]);

            if($checkRuleInfo === false){
                $clockRule = [];
            }else{
                $clockRule['name']       = $checkRuleInfo['name'];
                $clockRule['start_time'] = secondToHour($checkRuleInfo['start_time']);
                $clockRule['end_time']   = secondToHour($checkRuleInfo['end_time']);
            }
        }else{
            $clockRule = [];
        }

        $userInfo['clock_rule'] = $clockRule;

        $personId = UserSection::getVal(['id' => $userInfo['section_id']], 'person_id');
        $userInfo['person_name'] = $personId ? User::getVal(['id' => $personId], 'name') : '-';

        $mobile = UserResume::getVal(['user_id' => $userInfo['id']], 'mobile');

        if($userInfo['person_name'] != '-' && $mobile) $userInfo['person_name'] .= ' ( ' . $mobile . ' ) ';

        unset($userInfo['check_clock_id']);
        return Json::success('ok', $userInfo);
    }

    /**
     * 修改密码
     */
    public function setPass()
    {
        $passwordOld = Request()->param('password_old', '');
        $password    = Request()->param('password', '');
        if(empty($passwordOld)) return Json::fail('原密码不能为空');
        if(empty($password)) return Json::fail('新密码不能为空');
        if($passwordOld == $password) return Json::fail('新密码与原密码相同');
        if(strlen($password) < 6) return Json::fail('新密码长度为6-18位');
        if(strlen($password) > 18) return Json::fail('新密码长度为6-18位');

        $userInfo = User::getFind(['id' => $this->user_id]);

        if(setPass($passwordOld, $userInfo['salt']) != $userInfo['password']) return Json::fail('原密码错误');

        $flag = User::edit(['id' => $this->user_id, 'password' => setPass($password, $userInfo['salt'])]);
        if(!$flag) return Json::fail('修改失败');
        return Json::success('修改成功');
    }

    /**
     * 获取员工简历列表
     */
    public function getUserResumeList()
    {
        $page         = Request()->param('page', 1);
        $searchName   = Request()->param('search_name', '');
        $searchMobile = Request()->param('search_mobile', '');

        if(!empty($searchName)) $where[] = ['name', 'like', '%' . $searchName . '%'];
        if(!empty($searchMobile)) $where[] = ['mobile', 'like', '%' . $searchMobile . '%'];

        $userIds = User::getCol(['is_staff' => 1], 'id');

        $where[] = ['user_id', 'in', $userIds];

        $field = 'id, name, sex, birthday, education, mobile, expect_jobs, card_num, wage, address, jobs_status, create_time';
        $list = UserResume::getList($where, 1, $page, 20, $field, 'create_time DESC');
        if($list === false) return Json::fail('暂无数据');

        $edu       = [0 => '其他', 1 => '小学', 2 => '初中', 3 => '高中', 4 => '大专', 5 => '本科', 6 => '硕士', 7 => '博士'];
        $sex       = [1 => '男', 2 => '女'];
        $jobStatus = [1 => '在职', 2 => '离职'];

        foreach($list as &$info){
            $info['sex']             = $sex[$info['sex']];
            $info['birthday']        = date('Y-m-d', $info['birthday']);
            $info['education']       = $edu[$info['education']];
            $info['jobs_status']     = $jobStatus[$info['jobs_status']];
            
            if($info['share_user_name']){
                $info['share_user_name'] = User::getVal(['id' => $info['share_user_id']], 'name');
            }else{
                $info['share_user_name'] = '';
            }
        }

        return Json::success('ok', $list, UserResume::getNum($where));
    }

    /**
     * 获取员工列表
     */
    public function getUserList()
    {
        $page  = Request()->param('page', 1);
        $isAll = Request()->param('is_all', 0);

        $companyId  = Request()->param('company_id', 0);
        $sectionId  = Request()->param('section_id', 0);
        $searchName = Request()->param('search_name', '');
        $status     = Request()->param('status', 0);

        $where[] = ['is_staff', '=', 1];
        $where[] = ['id', '>', 1];

        if($companyId != 0) $where[] = ['company_id', '=', $companyId];
        if($sectionId != 0) $where[] = ['section_id', '=', $sectionId];
        if(!empty($status) && $status != -1) $where[] = ['status', '=', $status];

        if(!empty($searchName)){
            $userIds = User::getCol([['name|staff_no', 'like', '%' . $searchName . '%']], 'id');
            $where[] = ['id', 'in', $userIds];
        }

        $field = 'id, name, staff_no, card_num, role_id, section_id, section_level_id, avatars, subsidy, social, rule_salary_id, status, check_clock_id, last_time, job_time, quit_time';

        if($isAll == 0){
            $userList = User::getList($where, 1, $page, 20, $field, 'section_id, section_level_id, id');
        }else{
            $userList = User::getList($where, 0, 0, 0, 'id, name');
        }
        
        if($userList === false) return Json::fail('暂无数据');

        if(!$isAll){
            foreach($userList as &$info){
                if($info['section_id'] > 0 ){
                    $info['section'] = UserSection::getVal(['id' => $info['section_id']], 'name');
                    if($info['section_level_id']) $info['section'] .= '(' . UserSectionLevel::getVal(['id' => $info['section_level_id']], 'name') . ')';
                }else{
                    $info['section'] = '';
                }

                $checkRuleInfo = CheckRule::getFind(['id' => $info['check_clock_id']]);
                $info['check_clock_name'] = $checkRuleInfo['name'] . '（' . secondToHour($checkRuleInfo['start_time']) . '-' . secondToHour($checkRuleInfo['end_time']) . '）';
                $info['salary_name'] = RuleSalary::getVal(['id' => $info['rule_salary_id']], 'name');
                $info['role_name'] = SystemRole::getVal(['id' => $info['role_id']], 'name');
                $info['quit_time'] = $info['quit_time'] ? date('Y-m-d', $info['quit_time']) : '';
            }
        }

        return Json::success('ok', $userList, User::getNum($where));
    }

    /**
     * 员工编辑
     */
    public function setUser()
    {
        $param = input('');

        try{
            validate(UserValidate::class)->scene('edit')->check($param);
        }catch(ValidateException $e){
            return Json::fail($e->getError());
        }

        if(empty($param['password'])){
            unset($param['password']);
        }else{
            $param['password'] = setPass($param['password'], User::getVal(['id' => $param['id']], 'salt'));
        }

        if(isset($param['create_time'])) unset($param['create_time']);
        if(isset($param['job_time'])) unset($param['job_time']);

        if(isset($param['status']) && $param['status'] == 2){
            $param['quit_time'] = time();
        }else if(isset($param['status']) && $param['status'] == 1){
            $param['quit_time'] = 0;
        }

        $flag = User::edit($param);
        if(!$flag) return Json::fail();
        return Json::success();
    }

    /**
     * 员工档案
     */
    public function getStaffNews()
    {
        $page  = Request()->param('page', 1);

        $userInfo = User::getFind(['id' => $this->user_id]);
        if(!$userInfo) return Json::fail('暂无数据');

        $where[] = ['is_staff', '=', 1];
        $where[] = ['id', '<>', $this->user_id];

        if($userInfo['section_id']){
            $where[] = ['section_id', '=', $userInfo['section_id']];
        }

        $field = 'id, name, staff_no, section_id, avatars';

        $userList = User::getList($where, 1, $page, 20, $field);
        if($userList === false) return Json::fail('暂无数据');

        foreach($userList as &$info){
            if($info['section_id'] > 0 ){
                $info['section'] = UserSection::getVal(['id' => $info['section_id']], 'name');
            }else{
                $info['section'] = '';
            }

            $info['count_claim']        = UserResume::getNum(['claim_user_id' => $info['id'], 'status' => 1]);
            $info['count_invite']       = UserResume::getNum(['claim_user_id' => $info['id'], 'status' => 2]);
            $info['count_pass']         = UserResume::getNum(['claim_user_id' => $info['id'], 'status' => 4]);
            $info['count_induction']    = UserResume::getNum(['claim_user_id' => $info['id'], 'status' => 5]);
            $info['count_face_no']      = UserResume::getNum(['claim_user_id' => $info['id'], 'status' => 6]);
            $info['count_pass_no']      = UserResume::getNum(['claim_user_id' => $info['id'], 'status' => 7]);
            $info['count_induction_no'] = UserResume::getNum(['claim_user_id' => $info['id'], 'status' => 8]);
            $info['count_quit']         = UserResume::getNum(['claim_user_id' => $info['id'], 'status' => 9]);
        }

        return Json::success('ok', $userList, User::getNum($where));
    }

    /**
     * 员工删除
     */
    public function delUser()
    {
        $userId = Request()->param('user_id', 0);
        $flag = User::destroy($userId);
        if(!$flag) return Json::fail();
        return Json::success();
    }


    /**
     * 获取员工列表
     */
    public function getStatusList()
    {
        $type      = Request()->param('type', 0);
        $sectionId = Request()->param('section_id', 0);

        $where = [];
        if($type != 0 && $sectionId == 0){
            $sectionId = UserSection::getCol(['cate_id' => $type], 'id');
            $where[] = ['section_id', 'in', $sectionId];
        }else if($type != 0 && $sectionId != 0){
            $where[] = ['section_id', '=', $sectionId];
        }

        $where[] = ['id', '>', 1];
        $where[] = ['is_staff', '=', 1];
        
        $list = User::getList($where, 0, 0, 0, 'id, name');
        if($list === false) $list = [];
        return Json::success('ok', $list);
    }

    /**
     * 入职申请列表
     */
    public function getInductionList()
    {
        $page  = Request()->param('page', 1);

        $where = [];

        $userInfo = User::getFind(['id' => $this->user_id]);
        $sectionInfo = UserSection::getFind(['id' => $userInfo['section_id']]);

        if($this->user_id != 1 && $sectionInfo['cate_id'] != 4){
            $where[] = ['section_id', '=', $userInfo['section_id']];
        }

        $field = 'id, section_id, name, mobile, status, back_msg, create_time, finish_time';
        $list = ApplyInduction::getList($where, 1, $page, 20, $field, 'status, id DESC');
        if($list === false) return Json::fail('暂无数据');

        foreach($list as &$info){
            $info['section']   = UserSection::getVal(['id' => $info['section_id']], 'name');
        }

        return Json::success('ok', $list, ApplyInduction::getNum($where));
    }

    /**
     * 入职申请通过
     */
    public function setInductionPass()
    {
        $inductionId    = Request()->param('induction_id', 0);
        $checkClockId   = Request()->param('check_clock_id', 0);
        $roleId         = Request()->param('role_id', 0);
        $ruleSalaryId   = Request()->param('rule_salary_id', 0);
        $probation      = Request()->param('probation', 0);
        $isTrial        = Request()->param('is_trial', -1);
        $isTrialSalary  = Request()->param('is_trial_salary', -1);

        if($inductionId == 0) return Json::fail('入职申请ID不能为空');
        if($checkClockId == 0) return Json::fail('考勤规则不能为空');
        if($roleId == 0) return Json::fail('角色不能为空');
        if($ruleSalaryId == 0) return Json::fail('工资规则不能为空');
        if($isTrial == -1) return Json::fail('是否试用期不能为空');
        if($isTrialSalary == -1) return Json::fail('是否试用期薪资不能为空');

        $info = ApplyInduction::getFind(['id' => $inductionId]);
        if($info === false) return Json::fail('数据错误');
        if($info['status'] != 1) return Json::fail('数据状态错误');

        $sectionInfo = UserSection::getFind(['id' => $info['section_id']]);

        self::beginTrans();
        try{
            $flag = ApplyInduction::edit(['id' => $inductionId, 'status' => 2, 'finish_time' => time()]);
            if($flag === false) throw new Exception('更新状态失败');

            $salt    = getRandStr();
            $staffNo = getStaffNo($info['section_id']);
            if(!$staffNo) throw new Exception('工号生成失败');

            $userData = [
                'id'               => $info['user_id'],
                'name'             => $info['name'],
                'staff_no'         => $staffNo,
                'salt'             => $salt,
                'company_id'       => $sectionInfo['company_id'],
                'password'         => setPass('qingze888', $salt),
                'mobile'           => $info['mobile'],
                'section_id'       => $info['section_id'],
                'section_level_id' => $info['section_level_id'],
                'card_num'         => $info['card_num'],
                'check_clock_id'   => $checkClockId,
                'role_id'          => $roleId,
                'rule_salary_id'   => $ruleSalaryId,
                'probation'        => $probation,
                'is_staff'         => 1,
                'is_trial'         => $isTrial,
                'is_trial_salary'  => $isTrialSalary,
                'job_time'         => strtotime($info['job_time']),
            ];

            if(User::edit($userData) === false) throw new Exception('更新员工信息失败');
            UserSection::setIncField(['id' => $info['section_id']], 'nums');

            /** 简历变成员工简历 */
            UserResume::editWhere(['is_staff' => 1], ['user_id' => $info['user_id']]);

            self::commitTrans();
        }catch(\Exception $e){
            self::rollbackTrans();
            return Json::fail($e->getMessage());
        }

        SystemMenu::delRed(0, 10, $info['user_id'], 3, 2, $inductionId);

        return Json::success('通过成功');
    }

    /**
     * 入职申请驳回
     */
    public function setInductionBack()
    {
        $inductionId = Request()->param('induction_id', 0);
        $backMsg     = Request()->param('back_msg', '');

        $info = ApplyInduction::getFind(['id' => $inductionId]);
        if($info === false) return Json::fail('数据错误');
        if($info['status'] != 1) return Json::fail('数据状态错误');
       
        $flag = ApplyInduction::edit(['id' => $inductionId, 'status' => 3, 'back_msg' => $backMsg, 'finish_time' => time()]);
        if($flag === false) throw new Exception('更新状态失败');

        SystemMenu::delRed($info['user_id'], 10, 1);

        return Json::success('驳回成功');
    }

    /**
     * 工资表
     */
    public function getSalaryList()
    {
        $page = Request()->param('page', 1);

        $where = [];

        if($this->user_id != 1){
            $sectionIds = UserSection::getCol(['cate_id' => 4], 'id');
            if(!$sectionIds) return Json::fail('暂无数据');

            $sectionLevelIds = UserSectionLevel::getCol([['section_id', 'in', $sectionIds]], 'id');
            if(!$sectionLevelIds) return Json::fail('暂无数据');

            $userIds = User::getCol([['section_level_id', 'in', $sectionLevelIds]], 'id');
            if(!$userIds) return Json::fail('暂无数据');

            if(in_array($this->user_id, $userIds) == false) $where[] = ['user_id', '=', $this->user_id];
        }

        $list = UserWages::getList($where, 1, $page, 20, '*', 'section, create_time DESC');
        if(!$list) return Json::fail('暂无数据');

        foreach($list as &$info){
            $info['salary_total'] = rounding($info['salary'] 
                + $info['salary_work']
                + $info['achiev']
                + $info['commission']
                + $info['attendance']
                + $info['meal']
                + $info['traffic']
                + $info['telephone']
                + $info['subsidy']
                + $info['social']
            );

            $info['create_time'] = date('Y-m', $info['date_time']);
        }

        return Json::success('ok', $list, UserWages::getNum($where));
    }

    /**
     * 生成工资表
     */
    public function setSalary()
    {
        $flag = User::setSalary();
        if($flag !== true) return Json::fail('生成失败');
        return Json::success('生成成功');
    }

    /**
     * 工资规则列表
     */
    public function getRuleSalaryList()
    {
        $page      = Request()->param('page', 1);
        $sectionId = Request()->param('section_id', 0);

        $where = [];

        if($sectionId != 0) $where[] = ['section_id' , '=', $sectionId];

        $list = RuleSalary::getList($where, 1, $page, 20, '*', 'section_id, grade');
        if(!$list) return Json::fail('暂无数据');

        foreach($list as &$info){
            $info['section_name'] = UserSection::getVal(['id' => $info['section_id']], 'name');
        }

        return Json::success('ok', $list, RuleSalary::getNum($where));
    }

    /**
     * 新增工资规则
     */
    public function addRuleSalary()
    {
        $param['section_id'] = Request()->param('section_id', 0);
        $param['name']       = Request()->param('name', '');
        $param['salary']     = Request()->param('salary', 0);
        $param['achiev']     = Request()->param('achiev', 0);
        $param['grade']      = Request()->param('grade', 0);

        $flag = RuleSalary::add($param);
        if(!$flag) return Json::fail('新增失败');
        return Json::success('新增成功');
    }

    /**
     * 编辑工资规则
     */
    public function setRuleSalary()
    {
        $param['id']         = Request()->param('rule_salary_id', 0);
        $param['section_id'] = Request()->param('section_id', 0);
        $param['name']       = Request()->param('name', '');
        $param['salary']     = Request()->param('salary', 0);
        $param['achiev']     = Request()->param('achiev', 0);
        $param['grade']      = Request()->param('grade', 0);

        $flag = RuleSalary::edit($param);
        if(!$flag) return Json::fail('编辑失败');
        return Json::success('编辑成功');
    }

    /**
     * 工资规则删除
     */
    public function delRuleSalary()
    {
        $ruleSalaryId = Request()->param('rule_salary_id', 0);
        if($ruleSalaryId == 0) return Json::fail('数据错误');

        if(User::getFind(['rule_salary_id' => $ruleSalaryId]) !== false) return Json::fail('该规则使用中，不能删除');

        $flag = RuleSalary::destroy($ruleSalaryId);
        if(!$flag) return Json::fail('删除失败');
        return Json::success('删除成功');
    }


    /**
     * 获取员工级别
     */
    public function getUserRole()
    {
        return Json::success('ok', User::getUserRole($this->user_id));
    }

    /**
     * 求职者简历库列表
     */
    public function getSupplierResumeList()
    {
        $page      = Request()->param('page', 1);
        $status    = Request()->param('status', -1);
        $companyId = Request()->param('company_id', 0);

        $where = [];

        if($status != -1) $where[] = ['status', '=', $status];
        if($companyId != 0) $where[] = ['company_id', '=', $companyId];

        $list = ResumeJob::getList($where, 1, $page, 20, '*', 'status, face_start_time DESC');
        if(!$list) return Json::fail('暂无数据');

        foreach($list as &$info){
            $info['user_name']    = UserResume::getVal(['user_id' => $info['user_id']], 'name');
            $info['company_name'] = UserCompany::getVal(['id' => $info['company_id']], 'name');
            $info['face_time']    = date('Y-m-d H:i', $info['face_start_time']) . '~' . date('H:i', $info['face_end_time']);
            $info['join_time']    = $info['join_time'] ? date('Y-m-d', $info['join_time']) : '';
        }

        return Json::success('ok', $list, ResumeJob::getNum($where));
    }

    /**
     * 求职者简历库通过
     */
    public function resumeJobPass()
    {
        $resumeJobId = Request()->param('resume_job_id', 0);
        $joinTime    = Request()->param('join_time', '');

        $info = ResumeJob::getFind(['id' => $resumeJobId]);
        if(!$info) return Json::fail('简历不存在');
        if($info['status'] != 0) return Json::fail('状态异常');

        $flag = ResumeJob::edit(['id' => $resumeJobId, 'status' => 1, 'join_time' => strtotime($joinTime), 'finish_time' => time()]);
        if(!$flag) return Json::fail();
        return Json::success();
    }

    /**
     * 求职者简历库驳回
     */
    public function resumeJobBack()
    {
        $resumeJobId = Request()->param('resume_job_id', 0);

        $info = ResumeJob::getFind(['id' => $resumeJobId]);
        if(!$info) return Json::fail('简历不存在');
        if($info['status'] != 0) return Json::fail('状态异常');

        $flag = ResumeJob::edit(['id' => $resumeJobId, 'status' => 2, 'finish_time' => time()]);
        if(!$flag) return Json::fail();
        return Json::success();
    }




    /**
     * 重置数据库
     */
    public function delBaseData()
    {
        $h = 'qz_';

        Db::execute("truncate table ". $h . "apply_expenses");
        Db::execute("truncate table ". $h . "apply_induction");
        Db::execute("truncate table ". $h . "apply_leave");
        Db::execute("truncate table ". $h . "apply_miss_card");
        Db::execute("truncate table ". $h . "apply_work_over");
        Db::execute("truncate table ". $h . "check_approve");
        Db::execute("truncate table ". $h . "check_clock");
        Db::execute("truncate table ". $h . "check_rule");
        Db::execute("truncate table ". $h . "feedback");
        Db::execute("truncate table ". $h . "job");
        Db::execute("truncate table ". $h . "job_qa");
        Db::execute("truncate table ". $h . "kpi_daily");
        Db::execute("truncate table ". $h . "kpi_record");
        Db::execute("truncate table ". $h . "menu_red");
        Db::execute("truncate table ". $h . "message");
        Db::execute("truncate table ". $h . "notice");
        Db::execute("truncate table ". $h . "notice_sign");
        Db::execute("truncate table ". $h . "okr_record");
        Db::execute("truncate table ". $h . "project");
        Db::execute("truncate table ". $h . "resume_education");
        Db::execute("truncate table ". $h . "resume_record");
        Db::execute("truncate table ". $h . "resume_work");
        Db::execute("truncate table ". $h . "rule_kpi");
        Db::execute("truncate table ". $h . "rule_salary");
        Db::execute("truncate table ". $h . "system_role");
        Db::execute("truncate table ". $h . "user");
        Db::execute("truncate table ". $h . "user_archives");
        Db::execute("truncate table ". $h . "user_resume");
        Db::execute("truncate table ". $h . "user_section");
        Db::execute("truncate table ". $h . "user_section_level");
        Db::execute("truncate table ". $h . "user_wages");
    }

    public function addUser()
    {
        $flag = User::add([
            'name'      => '超级管理员',
            'staff_no'  => '88888888',
            'password'  => '#>_<#b14cc6c5012ec74d1bcef29ee52107d3',
            'salt'      => '888',
            'role_id'   => 1,
            'is_staff'  => 0,
        ]);

        $token = $this->jwt($flag['id']);
        User::editWhere(['token' => $token], ['id' => $flag['id']]);
    }
}